#include "bh750.h"
//#include "delay.h"

#include "stdint.h"
/*
 *==============================================================================
 *函数名称：IIC_Delay
 *函数功能：IIC延时
 *输入参数：无
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void IIC_Delay(void) {
	uint8_t t = 10;
	while (t--);
	}
/*
 *==============================================================================
 *函数名称：I2C_Start
 *函数功能：IIC起始信号
 *输入参数：无
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void I2C_Start(void) {
	BH1750_SDA_Set();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
	}
/*
 *==============================================================================
 *函数名称：I2C_Stop
 *函数功能：IIC终止信号
 *输入参数：无
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void I2C_Stop(void) {
	BH1750_SDA_Clr();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Set();
	}
/*
 *==============================================================================
 *函数名称：IIC_Ack
 *函数功能：CPU产生一个ACK信号
 *输入参数：无
 *返回值：无
 *备  注：无
 *==============================================================================
 */
void IIC_Ack(void) {
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
	BH1750_SDA_Set();
	}
/*
 *==============================================================================
 *函数名称：IIC_NAck
 *函数功能：CPU产生一个NACK信号
 *输入参数：无
 *返回值：无
 *备  注：无
 *==============================================================================
 */
void IIC_NAck(void) {
	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
	}
/*
 *==============================================================================
 *函数名称：I2C_WaitAck
 *函数功能：IIC等待应答
 *输入参数：无
 *返回值：0：未收到应答信号；1：收到应答信号
 *备  注：无
 *==============================================================================
 */
uint8_t I2C_WaitAck(void) {
	uint8_t re;

	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	if (BH1750_SDA_DATA()) {
		re = 1;
		}
	else {
		re = 0;
		}

	BH1750_SCL_Clr();
	IIC_Delay();

	return re;
	}
/*
 *==============================================================================
 *函数名称：Send_Byte
 *函数功能：写入一个字节
 *输入参数：dat：需要写入的数据
 *返回值：无
 *备  注：数据手册提供
 *==============================================================================
 */
void Send_Byte(uint8_t dat) {
	uint8_t i;

	for (i = 0;i < 8;i++) {
		// 发送数据时，从高位依次写入
		if (dat & 0x80) {
			BH1750_SDA_Set();
			}
		else {
			BH1750_SDA_Clr();
			}
		IIC_Delay();
		BH1750_SCL_Set();
		IIC_Delay();
		BH1750_SCL_Clr();

		// dat左移1位
		dat <<= 1;
		}
	}
/*
 *==============================================================================
 *函数名称：IIC_Read_Byte
 *函数功能：IIC读取一个字节数据
 *输入参数：无
 *返回值：无
 *备  注：读取到的一个字节数据
 *==============================================================================
 */
uint8_t IIC_Read_Byte(void) {
	uint8_t i;
	uint8_t value;

	// 高位在前
	value = 0;

	// 循环读取8bit数据
	for (i = 0; i < 8; i++) {
		value <<= 1;   // 循环左移一位

		BH1750_SCL_Set();
		IIC_Delay();

		// 如果是“1”
		if (BH1750_SDA_DATA()) {
			value++;
			}

		BH1750_SCL_Clr();
		IIC_Delay();
		}

	return value;
	}
//BH1750写一个字节
//返回值	成功：0		失败：非0 
/*
 *==============================================================================
 *函数名称：BH1750_Byte_Write
 *函数功能：BH1750写一个字节
 *输入参数：data：要写入的数据
 *返回值：0：写入成功；1/2：写入失败
 *备  注：无
 *==============================================================================
 */
uint8_t BH1750_Byte_Write(uint8_t data) {
	I2C_Start();

	// 发送从设备地址，0：写
	Send_Byte(BH1750_Addr | 0);

	// 收到应答信号
	if (I2C_WaitAck() == 1) {
		return 1;
		}
	//发送控制命令
	Send_Byte(data);

	// 收到应答信号
	if (I2C_WaitAck() == 1) {
		return 2;
		}

	I2C_Stop();

	return 0;
	}


/*
 *==============================================================================
 *函数名称：Drv_Bh1750_Read_Measure
 *函数功能：读取BH1750测量数据
 *输入参数：无
 *返回值：0：读取失败；其他：光照强度
 *备  注：无
 *==============================================================================
 */
uint16_t Drv_Bh1750_Read_Measure(void) {
	uint16_t receData = 0;

	I2C_Start();

	// 发送从设备地址，1：读
	Send_Byte(BH1750_Addr | 1);

	if (I2C_WaitAck() == 1) {
		return 0;
		}

	// 读取高八位
	receData = IIC_Read_Byte();
	IIC_Ack();

	// 读取低八位
	receData = (receData << 8) + IIC_Read_Byte();
	IIC_NAck();
	I2C_Stop();

	return receData;   // 返回读取到的数据
	}

/*
 *==============================================================================
 *函数名称：Drv_Bh1750_Init
 *函数功能：初始化BH1750
 *输入参数：无
 *返回值：无
 *备  注：无
 *==============================================================================
 */
void Drv_Bh1750_Init(void) {

	GPIO_InitTypeDef GPIO_InitStruct = { 0 };

	__HAL_RCC_GPIOB_CLK_ENABLE();

	GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);


	// 给一个停止信号, 复位I2C总线上的所有设备到待机模式
	I2C_Stop();

	// BH1750上电
	BH1750_Byte_Write(POWER_ON);

	// 复位BH1750
	BH1750_Byte_Write(MODULE_RESET);

	// 写入测量模式
	BH1750_Byte_Write(Measure_Mode);
	}

/*
 *==============================================================================
 *函数名称：Med_Bh1750_GetLightIntensity
 *函数功能：获取光照强度
 *输入参数：无
 *返回值：光照强度
 *备  注：分辨率	光照强度（单位lx）=（High Byte  + Low Byte）/ 1.2 * 测量精度
 *==============================================================================
 */
	
float lux=0.0f;
float Med_Bh1750_GetLightIntensity(void) {
	return (float) (Drv_Bh1750_Read_Measure() / 1.1f * Resolurtion);   //返回测量光照强度
	}
